package com.myboxlab.common.exception.handler;

import java.io.PrintWriter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.exception.ExceptionUtils;
import org.apache.log4j.Logger;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import com.alibaba.fastjson.JSON;
import com.myboxlab.common.exception.BusinessException;
import com.myboxlab.common.resp.AppResponse;
import com.myboxlab.pojo.vo.BaseVo;

/**
 * 统一异常处理 优点：将 Controller 层的异常和数据校验的异常进行统一处理，减少模板代码，减少编码量， 提升扩展性和可维护性 缺点：只能处理 Controller 层未捕获（往外抛）的异常，对于
 * Interceptor（拦截器）层的异常，Spring 框架层的异常，就无能为力了
 * 
 */
@ControllerAdvice
public class GlobalExceptionHandler {
    private Logger logger = Logger.getLogger(getClass());

    public static final int DEFAULT_ERROR_CODE = 500;

    /**
     * 处理所有不可知的异常
     */
    // @ExceptionHandler(Exception.class)
    // @ResponseBody
    // AppResponse handleException(Exception e) {
    // logger.error(e.getMessage(), e);
    //
    // AppResponse response = new AppResponse();
    // response.setFail("操作失败！");
    // return response;
    // }

    /**
     * 处理所有业务异常
     * 
     * @param e
     * @return
     */
    @ExceptionHandler(BusinessException.class)
    @ResponseBody
    AppResponse handleBusinessException(BusinessException e) {
        logger.error(e.getMessage(), e);

        AppResponse response = new AppResponse();
        response.setFail(e.getMessage());
        return response;
    }

    @ExceptionHandler(value = Exception.class)
    public void defaultErrorHandler(HttpServletRequest request, Exception e,
            HttpServletResponse resp) throws Exception {
        logger.info("处理失败，接口是:" + request.getRequestURL().toString());
        logger.error("transferError:", e);

        // 根据不同请求返回不同内容
        PrintWriter writer = resp.getWriter();
        System.out.println("accept:" + request.getHeader("accept"));
        if (request.getHeader("accept").contains("json")) {
            resp.setContentType("text/JavaScript");// json
            BaseVo baseVo = new BaseVo(500, "系统异常", ExceptionUtils.getFullStackTrace(e));
            writer.write(JSON.toJSONString(baseVo));
            writer.close();
        } else {
            resp.sendRedirect("/error/500");
        }
    }
}
